﻿using System.Linq.Expressions;
using System.Linq.Extensions;
using System.Linq.PageList;
using Dyao.Book.Contract;
using Dyao.Book.Entity;
using Dyao.Book.Repository.Abstractions;
using Foundation.Core;

namespace Dyao.Book.Repository
{
    using Foundation.Replacement;

    /// <summary>
    /// 书源仓库仓储
    /// </summary>
    public class BookSourceWarehouseRepository : DataRepository<BookSourceWarehouseEntity>, IBookSourceWarehouseRepository
    {
        /// <inheritdoc cref="IBookSourceWarehouseRepository.BulkUpdateAsync"/>
        public new Task BulkUpdateAsync(IEnumerable<BookSourceWarehouseEntity> entities, Expression<Func<BookSourceWarehouseEntity, object>> updateSelector, CancellationToken cancellationToken = default)
        {
            return base.BulkUpdateAsync(entities, op =>
            {
                op.ColumnPrimaryKeyExpression = key => new { key.ID };
                op.IncludeOnUpdateExpression = updateSelector;
            }, cancellationToken);
        }

        /// <inheritdoc cref="IBookSourceWarehouseRepository.GetAllListAsync"/>
        public async Task<List<BookSourceWarehouseDto>> GetAllListAsync(CancellationToken cancellationToken)
        {
            var query = this.GetQueryable()
                .Where(s => s.Enabled)
                .Select(bs => new BookSourceWarehouseDto()
                {
                    Id = bs.ID,
                    Header = bs.Header,
                    Name = bs.Name,
                    SearchUrl = bs.SearchUrl,
                    SpiderRule = bs.SpiderRule,
                    Url = bs.Url,
                    SourceKey = bs.SourceKey,
                });

            return await query.ToListAsync(cancellationToken);
        }

        /// <inheritdoc cref="IBookSourceWarehouseRepository.GetPageListAsync"/>
        public async Task<IPageList<BookSourceWarehouseEntity>> GetPageListAsync(IPageFilter<BookSourceSettingFilterDto> pageFilter, CancellationToken cancellationToken = default)
        {
            var filter = pageFilter.Filter;
            var query = this.GetQueryable()
                .WhereIf(bs => bs.Name.Contains(filter.Name), !filter.Name.IsNullOrEmpty())
                .WhereIf(bs => bs.SourceKey.Contains(filter.SourceKey), !filter.SourceKey.IsNullOrEmpty())
                .AsNoTracking();

            return await query.ToPageListAsync(pageFilter, cancellationToken);
        }

        /// <inheritdoc cref="IBookSourceWarehouseRepository.GetListByTitleAsync"/>
        public async Task<List<T>> GetListByIdsAsync<T>(List<string> ids, Expression<Func<BookSourceWarehouseEntity, T>> selector, CancellationToken cancellationToken)
        {
            if (ids.IsNullOrEmpty())
                return Enumerable.Empty<T>().ToList();

            var query = this.GetQueryable()
                .Where(b => ids.Contains(b.ID))
                .Select(selector);

            return await query.ToListAsync(cancellationToken);
        }

        /// <inheritdoc cref="IBookSourceWarehouseRepository.GetByIdAsync"/>
        public async Task<BookSourceWarehouseEntity> GetByIdAsync(string id, CancellationToken cancellationToken)
        {
            var query = this.GetQueryable()
                .Where(b => b.ID == id);

            return await query.FirstOrDefaultAsync(cancellationToken);
        }
    }
}
